package com.example.lib_common.websocket;

import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.example.lib_common.utils.LoggerUtils;

import org.java_websocket.handshake.ServerHandshake;
import org.w3c.dom.Text;

import java.net.URI;

/**
 * @author yaotianxue
 * @description
 * @date 2024/10/29
 */
public class WebSocketUtils {
    private ZWebSocketClient mWebSocketClient;
    private String websocket_url = "10.161.9.80:7015/api/websocket/108";
    private ReceiveMsgListener listener;

    public void setListener(ReceiveMsgListener listener) {
        this.listener = listener;
    }

    private WebSocketUtils(Builder builder){
        if(!TextUtils.isEmpty(builder.websocket_url)){
            this.websocket_url = builder.websocket_url;
        }
        this.listener = builder.listener;
        initWS();
    }

    /**
     * 初始化websocket
     */
    private void initWS() {
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//开启心跳检测
        if(null == mWebSocketClient){
            initWebSocket(); //创建client
        }else if(mWebSocketClient.isClosed()){
            reconnectWs();//重新链接
        }

    }

    /**
     * 实例化client对象
     */
    private void initWebSocket() {
        LoggerUtils.d("123", "websocket的地址是：ws://" + websocket_url);
        URI uri = URI.create("ws://" + websocket_url);
        mWebSocketClient = new ZWebSocketClient(uri){
            @Override
            public void onClose(int code, String reason, boolean remote) {
                super.onClose(code, reason, remote);
                if(null != listener){
                    listener.onClose(code, reason, remote);
                }
            }

            @Override
            public void onMessage(String message) {
                super.onMessage(message);
                if (!message.equals("Heartbeat")){
                    if(null != listener){
                        listener.onReceive(message);
                    }
                }
            }

            @Override
            public void onOpen(ServerHandshake handshakedata) {
                super.onOpen(handshakedata);
                if(null != listener){
                    listener.onOpen(handshakedata);
                }
            }

            @Override
            public void onError(Exception ex) {
                super.onError(ex);
                if(null != listener){
                    listener.onError(ex);
                }
            }
        };
        //TODO 设置超时时间
        mWebSocketClient.setConnectionLostTimeout(110 * 1000);
        //TODO 连接websocket
        new Thread() {
            @Override
            public void run() {
                try {
                    //connectBlocking多出一个等待操作，会先连接再发送，否则未连接发送会报错
                    mWebSocketClient.connectBlocking();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();


    }

    /**
     * 开启重连
     */
    private void reconnectWs() {
        mHandler.removeCallbacks(heartBeatRunnable);
        new Thread() {
            @Override
            public void run() {
                try {
                    LoggerUtils.d("123", "开启重连");
                    mWebSocketClient.reconnectBlocking(); //重连
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    /**
     * 发送消息
     * @param msg
     */
    public void sendMsg(String msg){
        if(null != mWebSocketClient && mWebSocketClient.isOpen()){
            LoggerUtils.d("123",String.format("Websocket发送的消息:%s",msg));
            mWebSocketClient.send(msg);
        }
    }

    /**
     * 断开链接
     */
    public void disconnect(){
        try {
            //关闭websocket
            if(null != mWebSocketClient){
                mWebSocketClient.close();
            }
            //停止心跳
            if(null != mHandler){
                mHandler.removeCallbacksAndMessages(null);
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            mWebSocketClient = null;
        }
    }


    /**
     * WebSocket 心跳逻辑
     * 每隔10秒进行一次对长连接的心跳检测
     */
    private static final long HEART_BEAT_RATE = 10 * 1000;
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if(null != mWebSocketClient){
                if(!mWebSocketClient.isOpen()){
                    LoggerUtils.d("123", "心跳包检测websocket连接状态1"+mWebSocketClient.isOpen() + "/" + websocket_url);
                    reconnectWs();//心跳机制发现断开开启重连

                }else{
                    LoggerUtils.d("123", "心跳包检测websocket连接状态2"+mWebSocketClient.isOpen() + "/" + websocket_url);
                    sendMsg("Heartbeat");
                }
            }else{
                initWebSocket();
            }
            //每隔一定的时间，对长连接进行一次心跳检测
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };







    public static class Builder{
        private String websocket_url;
        private ReceiveMsgListener listener;

        public Builder setWebsocketUrl(String websocket_url){
            this.websocket_url = websocket_url;
            return this;
        }

        public Builder setListener(ReceiveMsgListener listener){
            this.listener = listener;
            return this;
        }
        public WebSocketUtils build(){
            return new WebSocketUtils(this);
        }
    }





    /**
     * 接收到消息监听
     */
    public interface ReceiveMsgListener{
        void onReceive(String message);
        void onOpen(ServerHandshake handshakedata);
        void onError(Exception ex);
        void onClose(int code, String reason, boolean remote);
    }

}
